package calao.storage.bdb;

import java.util.Comparator;
import java.util.Vector;

import com.sleepycat.je.DatabaseException;

import calao.util.Cursor;
import calao.storage.Record;
import calao.storage.Field;
import calao.storage.DirectAccess;

public class RecordSorter
implements Comparator<Record>
{
		
	final TableCursor source;
	final Field[] sortFields;
	
	Record[] records;
	
	RecordSorter(TableCursor source, Field[] sortFields)
	{
		this.source = source;
		this.sortFields = sortFields;
	}	

	@SuppressWarnings("unchecked")
	public int compare(Record r1, Record r2) 
	{
		for (Field field : sortFields) {
			Object v1 = DirectAccess.get(r1, field);
			Object v2 = DirectAccess.get(r2, field);
			int result = field.getType().compare(v1, v2);
			if (result<0) return -1;
			if (result>0) return 1;
		}
		return 0;
	}
	
	Cursor<Record> sort()
	{
		Vector<Record> recordsList = new Vector<Record>();
		while (source.next()) recordsList.add(source.get());
		source.close();
		records = recordsList.toArray(new Record[recordsList.size()]);
		java.util.Arrays.sort(records, this);
		return new Cursor<Record>() {
			int i = -1;
			public void close() {
				records = null;
			}
			public Record get() {
				return records[i];
			}

			public boolean next() {
				return ++i<records.length;
			}
			public long skipNext(long count) {
				if (count<0) throw new IllegalArgumentException();
				long rem = records.length - i - 1;
				if (count<=rem) {
					i += count;
					return count;
				}
				else {
					i = records.length;
					return rem>0? rem : 0;
				}
			}
			public void delete() {
				try {
					source.tdb.drop(get().getPrimaryKey());
				}
				catch (DatabaseException e) {
					throw new RuntimeException(e);
				}
			}
			public void set(Record rec) {
				try {
					Record current = get();
					if (rec.getTable()!=current.getTable()) {
						throw new IllegalArgumentException();
					}
					source.tdb.replace(current, rec);
				}
				catch (DatabaseException e) {
					throw new RuntimeException(e);
				}
			}
		};
	}
		
}
